package com.raymond.cmpp.session;

import cn.hutool.core.util.ClassUtil;
import com.raymond.client.codec.BraidedDecoder;
import com.raymond.client.codec.decoding.BaseDecoder;
import com.raymond.client.codec.encodeing.BaseEncoder;
import com.raymond.client.config.ClientSocketConfig;
import com.raymond.client.connector.DefaultClientConnector;
import com.raymond.client.service.RecvHandlerProcessors;
import com.raymond.client.session.AbstractClientSession;
import com.raymond.client.session.AbstractClientSessionManager;
import com.raymond.cmpp.codec.annotation.MsgCodec;
import com.raymond.cmpp.config.CmppClientSocketConfig;
import com.raymond.cmpp.enums.CommandIdType;
import com.raymond.cmpp.handler.ActiveTestRequestMessageHandler;
import com.raymond.cmpp.handler.DeliverRequestMessageHandler;

import java.util.Set;

/**
 * 连接session管理器
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2022-11-01 10:27
 */
public class CmppClientSessionManager extends AbstractClientSessionManager {
    private BraidedDecoder codec2 = new BraidedDecoder();
    private BraidedDecoder codec3 = new BraidedDecoder();
    private RecvHandlerProcessors handlerProcessors = new RecvHandlerProcessors();


    public CmppClientSessionManager() {
        super(new DefaultClientConnector());
        init();
    }
    private void init() {
        try {
            init("com.raymond.cmpp.codec.cmpp3", 3);
            init("com.raymond.cmpp.codec.cmpp3", 2);
            init("com.raymond.cmpp.codec.cmpp2", 2);
//            int version3 = 0X30;
//            if (version != version3) {
//                init("com.raymond.cmpp.codec.cmpp2", 2);
//            }
            handlerProcessors.putBaseHandler(CommandIdType.DELIVER_REQUEST.getCommandId(), new DeliverRequestMessageHandler());
            handlerProcessors.putBaseHandler(CommandIdType.ACTIVE_TEST_REQUEST.getCommandId(), new ActiveTestRequestMessageHandler());
        } catch (IllegalAccessException | InstantiationException e) {
            throw new RuntimeException("初始化编解码类异常", e);
        }
    }

    /**
     * 初始化编解码类
     * @param packageName 包路径
     * @throws IllegalAccessException 异常
     * @throws InstantiationException 异常
     */
    public void init(String packageName, int version) throws IllegalAccessException, InstantiationException {
        BraidedDecoder codec = version == 2 ? codec2 : codec3;
        Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(packageName, MsgCodec.class);
        for (Class<?> aClass : classes) {
            if (BaseDecoder.class.isAssignableFrom(aClass)) {
                codec.putBaseDecoder(aClass.getAnnotation(MsgCodec.class).commandId().getCommandId()
                        , (BaseDecoder) aClass.newInstance());
            }
            if (BaseEncoder.class.isAssignableFrom(aClass)) {
                codec.putBaseEncoder(aClass.getAnnotation(MsgCodec.class).commandId().getCommandId()
                        , (BaseEncoder) aClass.newInstance());
            }
        }
    }

    @Override
    public AbstractClientSession createSession(ClientSocketConfig socketConfig) {
        return new CmppClientSession(this, (CmppClientSocketConfig) socketConfig);
    }


    public BraidedDecoder getCodec2() {
        return codec2;
    }

    public BraidedDecoder getCodec3() {
        return codec3;
    }

    public RecvHandlerProcessors getHandlerProcessors() {
        return handlerProcessors;
    }
}
